<?php

namespace common\logics\trade;

use Yii;
use yii\db\Exception;
use yii\helpers\ArrayHelper;
use common\helpers\MathHelper;
use common\models\shop\ShopOrder;
use common\models\shop\ShopOrderUnified;
use common\models\shop\ShopProductStats;
use common\logics\order\RecordOrderLog;
use common\models\shop\ShopOrderService;
use common\models\shop\ShopOrderRefund;

/**
 * 交易成功后异步通知业务处理
 *
 * @author emhome <emhome@163.com>
 * @since 2.0
 */
trait BusinessNotifyTrait {

    /**
     * 商城业务更新
     * @param string $msg
     * @return bool
     */
    protected function notifyToShop(&$msg) {
        $trade = $this->trade;
        Yii::error([
            '收到业务通知',
            $trade->attributes
        ], 'payment');
        $order = ShopOrderUnified::findOne([
            'order_no' => $trade->bizno
        ]);
        if ($order == null) {
            $msg = '商城业务订单【' . $trade->bizno . '】不存在！';
            return false;
        }
        $payCredit = intval($trade->credit * 10);
        $payAmount = $trade->total;

        $order->trade_id = $trade->id;
        $order->trade_no = $trade->trade_no;
        $order->pay_time = $trade->updated_at;
        $order->pay = $payAmount;
        $order->pay_credit = $payCredit;
        if ($order->status == ShopOrderUnified::STATUS_DEFAULT || $order->status == ShopOrderUnified::STATUS_ACTIVE) {
            $order->status = ShopOrderUnified::STATUS_PAID;
        }

        $shopOrders = $order->orders;
        $shopOrderGoods = $order->goods;
        $shopOrderDiscounts = $order->discounts;
        $goodsDiscounts = [];
        foreach ($shopOrderDiscounts as $orderDiscount) {
            if (isset($goodsDiscounts[$orderDiscount->order_goods_id])) {
                $goodsDiscounts[$orderDiscount->order_goods_id] += $orderDiscount->discount;
            } else {
                $goodsDiscounts[$orderDiscount->order_goods_id] = $orderDiscount->discount;
            }
        }

        //开启事务
        $transaction = Yii::$app->db->beginTransaction();
        try {
            if (!$order->save()) {
                Yii::error($order->getErrorMsg(), 'payment');
                throw new Exception('商城业务订单保存失败！');
            }
            $shopOrderCredits = [];
            $tempCredit = $payCredit;
            foreach ($shopOrders as $shopOrder) {
                $shopOrder->trade_id = $trade->id;
                $shopOrder->trade_no = $trade->trade_no;
                $shopOrder->pay_time = $trade->updated_at;
                $shopOrder->status = ShopOrder::STATUS_PAID;
                if ($payAmount > 0 && $payCredit > 0) {
                    $curentCredit = ceil($shopOrder->pay / $payAmount * $payCredit);
                    if ($curentCredit > $tempCredit) {
                        $curentCredit = $tempCredit;
                    }
                    $tempCredit -= $curentCredit;
                    $shopOrder->pay_credit = $curentCredit;
                    if ($shopOrder->pay) {
                        $shopOrderCredits[$shopOrder->id] = [
                            'rate' => $curentCredit / 10 / $shopOrder->pay,
                            'credits' => $curentCredit,
                            'residue' => $curentCredit,
                        ];
                    }
                }
                if (!$shopOrder->save()) {
                    throw new Exception('商城子订单保存失败！');
                }

                //生效订单商品退款服务信息
                $services = $shopOrder->inEffectiveOrderServices;
                foreach ($services as $service) {
                    $service->setEnforce($shopOrder->pay_time);
                    if ($service->order_status_end < $shopOrder->status) {
                        $service->status = ShopOrderService::STATUS_SUCCESS;
                    }
                    if (!$service->save()) {
                        throw new Exception('商城订单服务生效失败');
                    }
                }

                //记录订单日志
                RecordOrderLog::safeRecord($shopOrder);
            }
            $productStats = [];
            foreach ($shopOrderGoods as $goods) {
                $goodsPayAmount = $goods->goods_price * $goods->goods_number;
                if (isset($goodsDiscounts[$goods->id])) {
                    $goods->goods_discount = $goodsDiscounts[$goods->id];
                    $goodsPayAmount -= $goods->goods_discount;
                }
                if ($goodsPayAmount > 0 && isset($shopOrderCredits[$goods->order_id])) {
                    $shopOrderCredit = $shopOrderCredits[$goods->order_id];
                    $orderResidueCredits = ArrayHelper::getValue($shopOrderCredit, 'residue');
                    //剩余积分大于0时
                    if ($orderResidueCredits > 0) {
                        $goodsUsedCredits = ceil($goodsPayAmount * ArrayHelper::getValue($shopOrderCredit, 'rate') * 10);
                        $subtractOrderResidueCredits = $orderResidueCredits - $goodsUsedCredits;
                        if ($subtractOrderResidueCredits <= 0) {
                            $goodsUsedCredits = $orderResidueCredits;
                            $subtractOrderResidueCredits = 0;
                        }
                        $goods->pay_credit = $goodsUsedCredits;
                        ArrayHelper::setValue($shopOrderCredits, [$goods->order_id, 'residue'], $subtractOrderResidueCredits);
                    }
                }
                if (!$goods->save()) {
                    Yii::error($goods->getErrorMsg(), 'payment');
                }

                //更新商品统计信息
                $stats = ShopProductStats::findOrNew([
                    'product_id' => $goods->product_id,
                    'goods_id' => $goods->goods_id,
                ]);
                if (!isset($productStats[$goods->product_id])) {
                    $productStats[$goods->product_id] = [
                        'product_id' => $goods->product_id,
                        'store_id' => $goods->store_id,
                        'nums' => 0,
                    ];
                }
                if ($stats->isNewRecord) {
                    $stats->sales = 0;
                    $stats->store_id = $goods->store_id;
                }
                $productStats[$goods->product_id]['nums'] += $goods->goods_number;
                $stats->sales += $goods->goods_number;
                if (!$stats->save()) {
                    Yii::error($stats->getErrorMsg(), 'payment');
                }
            }
            foreach ($productStats as $temp) {
                $stats = ShopProductStats::findOrNew([
                    'product_id' => $temp['product_id'],
                    'goods_id' => 0,
                ]);
                if ($stats->isNewRecord) {
                    $stats->sales = 0;
                    $stats->store_id = $temp['store_id'];
                }
                $stats->sales += $temp['nums'];
                if (!$stats->save()) {
                    Yii::error($stats->getErrorMsg(), 'payment');
                }
            }
            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            Yii::error($e->getMessage());
            return false;
        }
        return true;
    }

    /**
     * 商城商品退款更新
     * @param string $msg
     * @return bool
     */
    protected function notifyToShopRefund(&$msg) {
        /* @var $trade Trade */
        $trade = $this->trade;
        $orderRefund = ShopOrderRefund::findOne([
            'trade_id' => $trade->id,
        ]);
        if (!$orderRefund) {
            $msg = '业务退款内容【' . $trade->trade_no . '】不存在！';
            return false;
        }
        $orderRefund->refund_time = $trade->updated_at;
        $orderRefund->status = ShopOrderRefund::STATUS_SUCCESS;
        $orderRefund->mark = '退款已到账';
        if (!$orderRefund->save()) {
            Yii::error($orderRefund->getErrorMsg(), 'payment');
            $msg = '业务退款保存失败！';
            return false;
        }
        //继续退款流程下一步操作
        $orderRefund->nextWorkflow();

        $order = $orderRefund->order;
        if (!$order) {
            $msg = '退款已成功。业务订单未找到！';
            return true;
        }
        //退款总金额
        $refundAmount = $orderRefund->sameRefundAmount;
        $same = MathHelper::bccomp($refundAmount, $order->pay);
        if ($same !== 0) {
            return true;
        }
        //关闭订单
        $order->status = $order::STATUS_CLOSE;
        if (!$order->save()) {
            Yii::error($order->getErrorMsg(), 'payment');
            $msg = '订单关闭保存失败！';
            return false;
        }
        return true;
    }

    /**
     * 更新店铺订单状态
     */
    protected function updateStoreOrder($trade, $shopOrder, $payAmount, $payCredit, $tempCredit) {
        $shopOrder->trade_id = $trade->id;
        $shopOrder->trade_no = $trade->trade_no;
        $shopOrder->pay_time = $trade->updated_at;
        $shopOrder->status = ShopOrder::STATUS_PAID;
        if ($payAmount > 0 && $payCredit > 0) {
            $curentCredit = ceil($shopOrder->pay / $payAmount * $payCredit);
            if ($curentCredit > $tempCredit) {
                $curentCredit = $tempCredit;
            }
            $tempCredit -= $curentCredit;
            $shopOrder->pay_credit = $curentCredit;
            if ($shopOrder->pay) {
                Yii::error([
                    $curentCredit,
                    $shopOrder->pay,
                    $shopOrder->pay * 10,
                    $curentCredit / $shopOrder->pay * 10,
                ]);
                $shopOrderCredits[$shopOrder->id] = [
                    'rate' => $curentCredit / 10 / $shopOrder->pay,
                    'credits' => $curentCredit,
                    'residue' => $curentCredit,
                ];
            }
        }
        if (!$shopOrder->save()) {
            throw new Exception('商城子订单保存失败！');
        }
    }

}
